﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.IO;
using Newtonsoft.Json.Linq;
using System.Threading;

namespace WChat {
    /// <summary>
    /// 微信用户
    /// </summary>
    public class WXUser {
        private string path = WChat.path.paths;
        private SqlHandle sql = new SqlHandle();
        private SqlTest ss = new SqlTest();
        public string g_nickname;
        private string g_headimgurl = null;
        //用户id
        private string _userName;
        public string UserName {
            get {
                return _userName;
            }
            set {
                _userName = value;
            }
        }
        /// <summary>
        /// uin
        /// </summary>
        public string My_Uin() {
            return CookieDictionary.GetCookies(direct + "Wxuin");
        }

        public string Myuin { get; set; }
      

        /// <summary>
        /// 微信类型（0为公众号，4为微信团队，其余为好友）目前为止
        /// </summary>
        public string AttrStatus { get; set; }

        //图片id
        private string _msgid;
        public string MsgId {
            get {
                return _msgid;
            }
            set {
                _msgid = value;
            }
        }

        /// <summary>
        /// 获取
        /// </summary>
        private int Url;
        public int SUrl {
            get {
                return Url;
            }
            set {
                Url = value;
            }
        }

        /// <summary>
        /// 通过direct可以获取cookies
        /// </summary>
        private string direct;
        public string LoginRedirect {
            get {
                return direct;
            }
            set {
                direct = value;
            }
        }

      
        public static string RemoveHtml( string requestString ) {
            //删除脚本   
            requestString = Regex.Replace(requestString, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);

            //删除Html 标签  
            requestString = Regex.Replace(requestString, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"-->", "", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"<!--.*", "", RegexOptions.IgnoreCase);

            requestString = Regex.Replace(requestString, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&(nbsp|#160);", "   ", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
            requestString = Regex.Replace(requestString, @"&#(\d+);", "", RegexOptions.IgnoreCase);
            //将字符串转换为html编码的字符串。
            //requestString = HtmlEncode(requestString).Trim();
            //返回结果
            return requestString;
        }

        //昵称
        private string _nickName;
        public string NickName {
            get {
                return _nickName;
            }
            set {
                if (value != null) {
                    _nickName = RemoveHtml(value);
                }
            }
        }

        //为0的为好友和群
        private string verifyflag;
        public string VerifyFlag {
            get {
                return verifyflag;
            }
            set {
                verifyflag = value;
            }
        }

        public char SortTag() {
            char sort='\0';
            if(ShowPinYin!=string.Empty){
               char[] char_sort = ShowPinYin.ToLower().ToCharArray();
                return char_sort[0];
            }
            else {
                return sort;
            }
             }

        //为0的为好友和群
        private string contactflag;
        public string ContactFlag {
            get {
                return contactflag;
            }
            set {
                contactflag = value;
            }
        }

        //头像url
        private string _headImgUrl;
        public string HeadImgUrl {
            get {
                return _headImgUrl;
            }
            set {
                _headImgUrl = value;
            }
        }
        public string PYInitial { get; set; }
        //备注名
        private string _remarkName;
        public string RemarkName {
            get {
                return _remarkName;
            }
            set {
                _remarkName = value;
            }
        }
        //性别 男1 女2 其他0
        private string _sex;
        public string Sex {
            get {
                return _sex;
            }
            set {
                _sex = value;
            }
        }
        //签名
        private string _signature;
        public string Signature {
            get {
                return _signature;
            }
            set {
                _signature = value;
            }
        }
        //城市
        private string _city;
        public string City {
            get {
                return _city;
            }
            set {
                _city = value;
            }
        }
        //省份
        private string _province;
        public string Province {
            get {
                return _province;
            }
            set {
                _province = value;
            }
        }
        //昵称全拼？
        private string _NickNamePYQuanPin;
        public string NickNamePYQuanPin {
            get { return _NickNamePYQuanPin; }
            set { _NickNamePYQuanPin = value; }
        }
        //昵称全拼
        private string _pyQuanPin;
        public string PYQuanPin {
            get {
                return _pyQuanPin;
            }
            set {
                _pyQuanPin = value;
            }
        }
        //备注名全拼
        private string _remarkPYQuanPin;
        public string RemarkPYQuanPin {
            get {
                return _remarkPYQuanPin;
            }
            set {
                _remarkPYQuanPin = value;
            }
        }
        //头像
        private bool _loading_icon = false;
        private Image _icon;
        public Image Icon {
            get {
                if (_icon == null && !_loading_icon) {
                    _loading_icon = true;
                    ((Action)(delegate () {
                        WXService wxs = new WXService();
                        if (_userName.Contains("@@"))  //讨论组
                        {
                            _icon = wxs.GetHeadImg(_userName, direct, Url);
                        }
                        else if (_userName.Contains("@"))  //好友
                        {
                            _icon = wxs.GetIcon(_userName, direct, Url);
                        }
                        else {
                            _icon = wxs.GetIcon(_userName, direct, Url);
                        }
                        _loading_icon = false;
                   })).BeginInvoke(null, null);
                }
                return _icon;
            }
        }




        private Image _icons;
        public Image Icons {
            get {
                if (_icons == null) {
                        WXService wxs = new WXService();
                        if (_userName.Contains("@@"))  //讨论组
                        {
                            _icons = wxs.GetHeadImg(_userName, direct, Url);
                        }
                        else if (_userName.Contains("@"))  //好友
                        {
                            _icons = wxs.GetIcon(_userName, direct, Url);
                        }
                        else {
                            _icons = wxs.GetIcon(_userName, direct, Url);
                        }
                }
                return _icon;
            }
        }

        //群聊中成员的头像
        private Image _gicon;
        public Image GrIcon( string UserName ) {
            WXService wxs = new WXService();
            _gicon = wxs.GetIcon(UserName, direct, Url);
            return _gicon;
        }

        /// <summary>
        /// 获取缩略图片
        /// </summary>
        private Image _pic;
        public Image Pic {
            get {
                WXService wxs = new WXService();
                _pic = wxs.GetPic(_msgid, direct, Url);
                return _pic;
            }
        }

        /// <summary>
        /// 获取真实图片,并保存在只定文件夹
        /// </summary>
        /// 
        private Image _tpic;
        public void SavePic() {
            WXService wxs = new WXService();
            _tpic = wxs.GetTruePic(_msgid, direct, Url);
            string path = WChat.path.paths;
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);
            try {
                _tpic.Save(path + "\\" + _msgid + ".jpg");
            } catch { }
        }

        public void Download_File( string from_user_name, string mediaid, string filename ) {
            WXService wxs = new WXService();
            wxs.GetMedia(from_user_name, mediaid, direct, filename, Url);
        }
        /// <summary>
        /// 获取语音
        /// </summary>
        /// <param name="msgid"></param>
        public void getvoice(string msgid) {
            WXService wxs = new WXService();
            wxs.GetVoice( msgid, direct, Url);
        }
    

        //public void GetVideo( string msgid ) {
        //    WXService wxs = new WXService();
        //    wxs.getvideo(msgid, direct, Url);
        //}

        /// <summary>
        /// 通过好友请求
        /// </summary>
        /// <param name="value"></param>
        /// <param name="user_ticket"></param>
        public void verify_usr( string value, string user_ticket ) {
            WXService wxs = new WXService();
            wxs.VerifyUser(value, user_ticket, direct, Url);
        }
        /// <summary>
        /// 显示名称
        /// </summary>
        public string ShowName {
            get {
                return (_remarkName == null || _remarkName == "") ? _nickName : _remarkName;
            }
        }

        /// <summary>
        /// 显示的拼音全拼
        /// </summary>
        public string ShowPinYin {
            get {
                return (_remarkPYQuanPin == null || _remarkPYQuanPin == "") ? _pyQuanPin : _remarkPYQuanPin;
            }
        }

        public event MsgSentEventHandler MsgSent;
        public event MsgRecvedEventHandler MsgRecved;
   
        //发送给对方的消息 【存入数据字典】 
        private Dictionary<DateTime, WXMsg> _sentMsg = new Dictionary<DateTime, WXMsg>();
        public Dictionary<DateTime, WXMsg> SentMsg {
            get {
                return _sentMsg;
            }
        }
        //收到对方的消息 【存入数据字典】 
        private Dictionary<DateTime, WXMsg> _recvedMsg = new Dictionary<DateTime, WXMsg>();
        public Dictionary<DateTime, WXMsg> RecvedMsg {
            get {
                return _recvedMsg;
            }
        }

        //  获取图片 【存入数据字典】 
        private Dictionary<DateTime, WXUser> _recvedPic = new Dictionary<DateTime, WXUser>();
        public Dictionary<DateTime, WXUser> RecvedPic {
            get {
                return _recvedPic;
            }
        }

        #region 数据库操作
        /// <summary>
        /// 接收来自该用户的消息
        /// </summary>
        /// <param name="msg"></param>
        public void ReceiveMsg( string _me_nic, WXMsg msg ) {
            try {
                _recvedMsg.Add(msg.Time, msg);
            } catch(Exception e) {
                WriteLog.Writelog("ReceiveMsg", e.ToString());
            }
            if (msg.IsGroup && msg.CrewUserName!=string.Empty) {
                string picpath = path + "\\" + msg.CrewNickName + ".jpg";
                try {
                    if (!File.Exists(picpath)) {   //如果群头像不存在
                       // MessageBox.Show("无头像:" + msg.CrewUserName);
                        Image gi = GrIcon(msg.CrewUserName);     //开始获取
                        if (gi != null) {
                           // MessageBox.Show("头像不为空:" + msg.CrewUserName);
                            gi.Save(picpath);   //如果获取成功，则保存
                        }
                    }
                }
                catch (Exception e) {
                    WriteLog.Writelog("获取群员头像", e.ToString());
                }
            }
            if (msg.Type=="3") {
                string imgpath = path + "\\" + msg.MsgId + "small.jpg";
                try {
                    if (Pic != null) {
                        Pic.Save(imgpath);
                    }
                }
                catch (Exception e) {
                    WriteLog.Writelog("Receive图片", e.ToString());
                }
                Thread pic_dowen = new Thread(SavePic);  //在这里使用线程保存大图
                pic_dowen.Start();
            }
            if (msg.Type == "49" && msg.TxtUrl!=string.Empty) {
                string imgpath = path + "\\" + msg.MsgId + "small.jpg";
                try {
                    if (Pic != null) {
                        Pic.Save(imgpath);
                    }
                }  catch (Exception e) {
                    WriteLog.Writelog("ReceiveMsg链接下载图片", e.ToString());
                }
            }
            MsgRecved?.Invoke(msg);
            sql.insertChatLog(_me_nic, msg);
            if (My_Uin()!=string.Empty) {
                ss.insertChatLog(My_Uin(), msg);    //*************************************************************************
            }
            else {
                WriteLog.Writelog("ReceiveMsg-sqllite", "My_Uin为空");
            }
        }
        /// <summary>
        /// 同步自己在其他设备发送的消息
        /// </summary>
        /// <param name="msg"></param>
        public void Syc_SendMsg( string _me_nic, WXMsg msg) {
            try {
                _sentMsg.Add(msg.Time, msg);
            }
            catch (Exception e) {
                WriteLog.Writelog("Syc_SendMsg",e.ToString() );
            }
            if (msg.Type == "3") {
                string imgpath = path + "\\" + msg.MsgId + "small.jpg";
                try {
                    if (Pic != null) {
                        Pic.Save(imgpath);
                    }
                } catch (Exception e) {
                    WriteLog.Writelog("Syc_SendMsg保存图片", e.ToString());
                }
                Thread pic_dowen = new Thread(SavePic);  //在这里使用线程保存大图
                pic_dowen.Start();
            }
            if (msg.Type == "49" && msg.TxtUrl != string.Empty) {
                string imgpath = path + "\\" + msg.MsgId + "small.jpg";
                try {
                    if (Pic != null) {
                        Pic.Save(imgpath);
                    }
                } catch (Exception e) {
                    WriteLog.Writelog("Syc_SendMsg保存链接图片", e.ToString());
                }
            }
            MsgSent?.Invoke(msg);
            sql.insertChatLog(_me_nic, msg);
            if (My_Uin() != string.Empty) {
                ss.insertChatLog(My_Uin(), msg);    //*************************************************************************
            }
            else {
                WriteLog.Writelog("ReceiveMsg-sqllite", "My_Uin为空");
            }
        }

        public void InsertChatLog( string _me_nic, WXMsg msg ) {
            _sentMsg.Add(msg.Time, msg);
            sql.insertChatLog(_me_nic, msg);
            if (My_Uin() != string.Empty) {
                ss.insertChatLog(My_Uin(), msg);    //*************************************************************************
            }
            else {
                WriteLog.Writelog("ReceiveMsg-sqllite", "My_Uin为空");
            }
        }
        #endregion

        /// <summary>
        /// 向微信服务器发消息
        /// </summary>
        /// <param name="_menic"></param>
        /// <param name="msg"></param>
        /// <param name="showOnly"></param>
        public void SendMsgToServer( WXMsg msg ) {
            WXService wxs = new WXService();
            wxs.SendMsg(msg.Msg, msg.From, msg.To, int.Parse(msg.Type), direct, Url);
        }
        /// <summary>
        /// 向该用户文件
        /// </summary>
        /// <param name="msg"></param>
        public void SendFiles( WXUser from, WXUser to, string filename ) {
            FileInfo file = new FileInfo(filename);
            WXMsg msg = new WXMsg();
            WXService wxs = new WXService();
            string filetype = file.Extension.Split('.')[1].ToLower();
            string ful_nam = file.Name;
            if (filetype.Contains("ico") | filetype.Contains("gif") | filetype.Contains("xlsx") | filetype.Contains("pdf") | filetype.Contains("pptx") | filetype.Contains("docx") | filetype.Contains("jpg") | filetype.Contains("png") | filetype.Contains("bmp") | filetype.Contains("doc") | filetype.Contains("txt") | filetype.Contains("xls") | filetype.Contains("zip") | filetype.Contains("rar") | filetype.Contains("apk") | filetype.Contains("exe")) {
                switch (filetype) {
                case "jpg":
                msg.Type = "99";
                msg.Msg = "[图片]";
                msg.FileName = filename;
                wxs.SendPicMsg(from.UserName, to.UserName, filename, direct, Url);
                break;
                case "png":
                msg.Type = "99";
                msg.Msg = "[图片]";
                msg.FileName = filename;
                wxs.SendPicMsg(from.UserName, to.UserName, filename, direct, Url);
                break;

                case "gif":
                msg.Type = "99";
                msg.Msg = "[图片]";
                msg.FileName = filename;
                wxs.SendPicMsg(from.UserName, to.UserName, filename, direct, Url);
                break;

                case "ico":
                msg.Type = "99";
                msg.Msg = "[图片]";
                msg.FileName = filename;
                wxs.SendPicMsg(from.UserName, to.UserName, filename, direct, Url);
                break;

                case "bmp":
                msg.Type = "99";
                msg.Msg = "[图片]";
                msg.FileName = filename;
                wxs.SendPicMsg(from.UserName, to.UserName, filename, direct, Url);
                break;
                case "txt":
                msg.Type = "49";
                msg.FileSize = file.Length.ToString();
                msg.Msg = ful_nam;
                msg.TxtUrl = "";
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;
                case "doc":
                msg.TxtUrl = "";
                msg.Type = "49";
                msg.FileSize = file.Length.ToString();
                msg.Msg = ful_nam;
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;
                case "xls":
                msg.TxtUrl = "";
                msg.Type = "49";
                msg.FileSize = file.Length.ToString();
                msg.Msg = ful_nam;
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;
                case "zip":
                msg.TxtUrl = "";
                msg.Type = "49";
                msg.Msg = ful_nam;
                msg.FileSize = file.Length.ToString();
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;
                case "rar":
                msg.TxtUrl = "";
                msg.Type = "49";
                msg.Msg = ful_nam;
                msg.FileSize = file.Length.ToString();
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;
                case "apk":
                msg.Type = "49";
                msg.TxtUrl = "";
                msg.Msg = ful_nam;
                msg.FileSize = file.Length.ToString();
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;
                case "exe":
                msg.Type = "49";
                msg.TxtUrl = "";
                msg.Msg = ful_nam;
                msg.FileSize = file.Length.ToString();
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;

                case "xlsx":
                msg.Type = "49";
                msg.TxtUrl = "";
                msg.Msg = ful_nam;
                msg.FileSize = file.Length.ToString();
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;

                case "pdf":
                msg.Type = "49";
                msg.TxtUrl = "";
                msg.Msg = ful_nam;
                msg.FileSize = file.Length.ToString();
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;

                case "pptx":
                msg.Type = "49";
                msg.TxtUrl = "";
                msg.Msg = ful_nam;
                msg.FileSize = file.Length.ToString();
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;

                case "docx":
                msg.Type = "49";
                msg.TxtUrl = "";
                msg.Msg = ful_nam;
                msg.FileSize = file.Length.ToString();
                msg.FileName = filename;
                wxs.SendFiles(from.UserName, to.UserName, filename, direct, Url);
                break;

                }

                msg.Readed = false;
                msg.Time = DateTime.Now;
                msg.IsReceive = 1;
                msg.Fr_NickName = from.NickName;
                msg.To_NickName = to.NickName;
                if (My_Uin() != string.Empty) {
                    ss.insertChatLog(My_Uin(), msg);    //*************************************************************************
                }
                else {
                    WriteLog.Writelog("ReceiveMsg-sqllite", "My_Uin为空");
                }
                sql.insertChatLog(from.NickName, msg);
                _sentMsg.Add(msg.Time, msg);
            }
            else {
                MessageBox.Show("目前暂不支持此文件格式！");
            }

        }
        /// <summary>
        /// 获取该用户发送的未读消息
        /// </summary>
        /// <returns></returns>
        public List<WXMsg> GetUnReadMsg() {
            List<WXMsg> list = null;
            foreach (KeyValuePair<DateTime, WXMsg> p in _recvedMsg) {
                if (!p.Value.Readed) {
                    if (list == null) {
                        list = new List<WXMsg>();
                    }
                    list.Add(p.Value);
                }
            }
            return list;
        }
        /// <summary>
        /// 更新群好友
        /// </summary>
        /// <param name="username"></param>
        /// <param name="chatroom_nam"></param>
        public bool Updata_ChatRoom(string username, string chatroom_nam ) {   
            WXService wxs = new WXService();
            JObject result = wxs.UpdataChatRoom(direct, username, chatroom_nam,Url);
            if (result != null) {
                if (result["BaseResponse"]["Ret"].ToString() == "0") {
                    return true;
                }else{
                    if (result["BaseResponse"]["ErrMsg"].ToString()!=string.Empty) {
                        MessageBox.Show(result["BaseResponse"]["ErrMsg"].ToString());
                        return false;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// 建群
        /// </summary>
        /// <param name="us_count"></param>
        /// <param name="userList"></param>
        /// <param name="Topic">群名称</param>
       /// <returns></returns>
        public bool Create_ChatRoom( int us_count, List<string> userList,string Topic ) {
            WXService wxs = new WXService();
            JObject result = wxs.CreateChatRoom(direct, us_count, userList, Url, Topic);
            if (result != null) {
                if (result["BaseResponse"]["Ret"].ToString() == "0" && result["BaseResponse"]["ErrMsg"].ToString() == "Everything is OK") {
                    return true;
                }
                else {
                    if (result["BaseResponse"]["ErrMsg"].ToString() != string.Empty) {
                        MessageBox.Show(result["BaseResponse"]["ErrMsg"].ToString());
                    }
                    return false;
                }
            }
            return false;
        }

        public bool AddFriend( string speak, string userNam ) {
            WXService wxs = new WXService();
            JObject result = wxs.AddFriend(direct, speak, userNam, Url);
            if (result != null) {
                if (result["BaseResponse"]["Ret"].ToString() == "0") {
                    return true;
                } else {
                    if (result["BaseResponse"]["ErrMsg"].ToString() != string.Empty) {
                        MessageBox.Show(result["BaseResponse"]["ErrMsg"].ToString());
                    }
                }
            }
            return false;
        }

        //省份

        public WXMsg _msg;
        public WXMsg GetMsgs {
            get {
                return _msg;
            }
            set {
                _msg = value;
            }
        }
        /// <summary>
        /// 获取最近的一条消息
        /// </summary>
        /// <returns></returns>
        public WXMsg GetLatestMsg() {
            WXMsg msg = null;
            if (_sentMsg.Count > 0 && _recvedMsg.Count > 0) {
                msg = _sentMsg.Last().Value.Time > _recvedMsg.Last().Value.Time ? _sentMsg.Last().Value : _recvedMsg.Last().Value;
            }
            else if (_sentMsg.Count > 0) {
                msg = _sentMsg.Last().Value;
            }
            else if (_recvedMsg.Count > 0) {
                msg = _recvedMsg.Last().Value;
            }
            else {
                msg = null;
            }
            return msg;
        }

        /// <summary>
        /// 批量获取好友
        /// </summary>
        /// <param name="username"></param>
        public string Batch_Get_Contact( string username,string groupusername ) {
            string nickname = "";
            WXService wxs = new WXService();
            JObject bat = wxs.BatchGetContact(username, groupusername, direct, Url);
            if (bat != null) {
                foreach (var louser in bat["ContactList"]) {
                    nickname= louser["NickName"].ToString();
                    g_headimgurl = louser["HeadImgUrl"].ToString();
                }
            }
            return nickname;
        }

    }
    /// <summary>
    /// 表示处理消息发送完成事件的方法
    /// </summary>
    /// <param name="msg"></param>
    public delegate void MsgSentEventHandler( WXMsg msg );
    /// <summary>
    /// 表示处理接收到新消息事件的方法
    /// </summary>
    /// <param name="msg"></param>
    public delegate void MsgRecvedEventHandler( WXMsg msg );

    public delegate void PicRecvedEventHandler( WXMsg msg, WXUser sd );

    public delegate void locPicRecvedEventHandler( WXMsg msg );


} 

